#include <ptcCommandOpt.h>
#include <cmdDealCommon.h>

// ===coding by user self===
void sendPctResponseData(struct ptcCmdOptStruct *parseinform);
void ptcPackParseCbk(struct ptcPackOption *parseinform)
{
    struct ptcCmdOptStruct *tmpCmdOpt = (struct ptcCmdOptStruct *)parseinform->userdata;

    if(ptcCmdCheckAddress(tmpCmdOpt) < 0)
    {// addr diff
        return;
    }
    
    if (ptcPackGetDataSize(parseinform) < PTC_CMD_HEAD_PST_DATA)
    {
        logerror("size error:%d", ptcPackGetDataSize(parseinform));
        return;
    }

    switch (ptcPackGetCrypte(parseinform))
    {
    case protocolParseCrypte_None:
    {
        break;
    }
    case protocolParseCrypte_SM4Pre:
    {
        logerror("not surpport:%d", ptcPackGetCrypte(parseinform));
        return;
    }
    case protocolParseCrypte_SM4:
    {
        logerror("not surpport:%d", ptcPackGetCrypte(parseinform));
        return;
    }
    default:
    {
        logerror("not surpport:%d", ptcPackGetCrypte(parseinform));
        return;
    }
    }
    
    if(ptcDoCommandFunction(tmpCmdOpt) < 0)
    {
        logerror("cmd no responce:%d", ptcCmdGetCmdNB(tmpCmdOpt));
        return;
    }
    //responce.
    switch (ptcPackGetCrypte(parseinform))
    {
    case protocolParseCrypte_None:
    {
        break;
    }
    case protocolParseCrypte_SM4Pre:
    {
        logerror("not surpport:%d", ptcPackGetCrypte(parseinform));
        return;
    }
    case protocolParseCrypte_SM4:
    {
        logerror("not surpport:%d", ptcPackGetCrypte(parseinform));
        return;
    }
    default:
    {
        logerror("not surpport:%d", ptcPackGetCrypte(parseinform));
        return;
    }
    }
    ptcPackFinishData(parseinform);
    sendPctResponseData(tmpCmdOpt);
}

ptcPackType ptcCmdGetRemainSize(struct ptcCmdOptStruct *cmdOpt)
{
    return ptcPackGetRemainSize(&cmdOpt->parser) - PTC_CMD_HEAD_PST_DATA - 16/*for encrypte*/;
}

int ptcCmdCheckAddress(struct ptcCmdOptStruct *cmdOpt)
{
    const char MCU_CONST_TYPE tmpBoardAddr[16] = {0xff};    
    if(ptcPackCheckAddr(&cmdOpt->parser, tmpBoardAddr) == 0)
    {
        if(ptcCmdGetCmdNB(cmdOpt) == ptcCmdFuncEnumDef(SetReadSN))
        {
            // cmd 0 can be boardcast
            return 1;
        }
    }
    else if(ptcPackCheckAddr(&cmdOpt->parser, cmdOpt->deviceSerialNumber) == 0)
    {
        return 1;
    }
    return -1;
}

uint16_t ptcCmdGetCmdNB(struct ptcCmdOptStruct *cmdOpt)
{
    return convertOvtBigSysI16(ptr_value(uint16_t, &ptcPackGetUsrData(&cmdOpt->parser)[PTC_CMD_HEAD_PST_CMD_NUMB]));
}
int ptcCmdSetCmdNB(struct ptcCmdOptStruct *cmdOpt, uint16_t cmdid)
{
    uint16_t tmpvalue = convertOvtBigSysI16(cmdid);
    memcpy(&ptcPackGetUsrData(&cmdOpt->parser)[PTC_CMD_HEAD_PST_CMD_NUMB], &tmpvalue, sizeof(tmpvalue));
}

uint8_t ptcCmdGetCmdSn(struct ptcCmdOptStruct *cmdOpt)
{
    return ptcPackGetUsrData(&cmdOpt->parser)[PTC_CMD_HEAD_PST_CMD_SN];
}
int ptcCmdSetCmdSn(struct ptcCmdOptStruct *cmdOpt, uint8_t cmdserial)
{
    ptcPackGetUsrData(&cmdOpt->parser)[PTC_CMD_HEAD_PST_CMD_SN] = cmdserial;
    return cmdserial;
}

uint8_t ptcCmdGetCmdResp(struct ptcCmdOptStruct *cmdOpt)
{
    return ptcPackGetUsrData(&cmdOpt->parser)[PTC_CMD_HEAD_PST_RESP];
}
int ptcCmdSetCmdResp(struct ptcCmdOptStruct *cmdOpt, uint8_t cmdResp)
{
    ptcPackGetUsrData(&cmdOpt->parser)[PTC_CMD_HEAD_PST_RESP] = cmdResp;
    return cmdResp;
}

ptcPackType ptcCmdGetUserSize(struct ptcCmdOptStruct *cmdOpt)
{
    return ptcPackGetDataSize(&cmdOpt->parser) - PTC_CMD_HEAD_PST_DATA;
}
int ptcCmdSetUsrSize(struct ptcCmdOptStruct *cmdOpt, ptcPackType setsize)
{
    if(ptcCmdGetRemainSize(cmdOpt) < setsize)
    {
        logerror("error size:%d", setsize);
        return -1;
    }
    ptcPackSetDataSize(&cmdOpt->parser, PTC_CMD_HEAD_PST_DATA + setsize);
    return 0;
}

void *ptcCmdGetUsrPtr(struct ptcCmdOptStruct *cmdOpt)
{
    return &ptcPackGetUsrData(&cmdOpt->parser)[PTC_CMD_HEAD_PST_DATA];
}
int ptcCmdSetUsrData(struct ptcCmdOptStruct *cmdOpt, const void *usrdata, ptcPackType usrsize)
{
    if(ptcCmdGetRemainSize(cmdOpt) < usrsize)
    {
        logerror("error size:%d", usrsize);
        return -1;
    }
    memcpy(ptcCmdGetUsrPtr(cmdOpt), usrdata, usrsize);
    ptcPackSetDataSize(&cmdOpt->parser, PTC_CMD_HEAD_PST_DATA + usrsize);
    return usrsize;
}
